package com.itheima;

import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

/**
 * Delayed接口的实现类  也就是延迟队列中的元素
 */

public class MyDelayedTask implements Delayed {

    // 代表元素执行时间
    private int executeTime = 0;
    // 元素名称
    private final String name;

    /**
     * @param delay 元素延迟多久执行
     * @param name  元素名称
     */
    public MyDelayedTask(int delay, String name) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.SECOND, delay);

        this.executeTime = (int) (calendar.getTimeInMillis() / 1000);
        this.name = name;
    }

    /**
     * 剩余时间 = 执行时间 - 当前时间
     * 元素在队列中的剩余时间，单位为给定的时间单位
     *
     * @param unit the time unit
     * @return
     */
    @Override
    public long getDelay(TimeUnit unit) {
        Calendar calendar = Calendar.getInstance();
        return executeTime - (calendar.getTimeInMillis() / 1000);
    }

    /**
     * 元素排序
     *
     * @param o the object to be compared.
     * @return
     */
    @Override
    public int compareTo(Delayed o) {
        long delay = this.getDelay(TimeUnit.NANOSECONDS) - o.getDelay(TimeUnit.NANOSECONDS);
        return delay == 0 ? 0 : (delay > 0 ? 1 : -1);
    }

    @Override
    public String toString() {
        return "MyDelayedTask{" +
                "executeTime=" + executeTime +
                ", name='" + name + '\'' +
                '}';
    }

    public static void main(String[] args) throws InterruptedException {
        // 延迟阻塞队列
        DelayQueue<MyDelayedTask> queue = new DelayQueue<>();

        // 表示李四10秒后才能出队列
        queue.add(new MyDelayedTask(10, "李四"));
        queue.add(new MyDelayedTask(5, "张三"));
        queue.add(new MyDelayedTask(15, "王五"));

        System.out.println(new Date() + "start consume ");
        while (!queue.isEmpty()) {
            // 从队列中拉取一个元素
            // 这个poll是非阻塞的，如果队列中没有元素，得到的是null
//            MyDelayedTask delayedTask = queue.poll();
            // 他是阻塞方法，如果队列中没有元素，就会阻塞
            MyDelayedTask delayedTask = queue.take();
            if (delayedTask != null) {
                System.out.println(new Date() + "consume task" + delayedTask);
            }
            // 模拟消费者消费的时间 一秒
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }
}
